﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using USBInterface;

namespace WevPanel
{
    public partial class FormUserCurves : Form
    {
        public ObservableCollection<CurvePoint> torque_iq_curve = new ObservableCollection<CurvePoint>();
        public WaveGrapher grapher;
        public FormUserCurves()
        {
            InitializeComponent();
            grapher = new WaveGrapher(ref Zed);
            InitGraph();
        }

        private void InitGraph()
        {
            var pane = Zed.GraphPane;
            pane.YAxis.Title.Text = "y-series";
            pane.XAxis.MajorGrid.IsVisible = true;
            pane.YAxis.MajorGrid.IsVisible = true;

        }

        private void FormUserCurves_Load(object sender, EventArgs e)
        {
            torque_iq_curve.Add(new CurvePoint());
            CurveDataViewer.DataSource = torque_iq_curve;

            importDialog.Filter = "文本文件(*.txt)|*.txt";
            importDialog.InitialDirectory = Application.StartupPath;
            importDialog.FileName = "";
            importDialog.FileOk += (send, ev) => {
                var rd = new StreamReader(importDialog.FileName);
                try
                {
                    torque_iq_curve.Clear();
                    while (true)
                    {
                        var line = rd.ReadLine();
                        Console.WriteLine(line);
                        var point = line.Split((char)',');
                        if (point.Length < 2)
                            break;
                        torque_iq_curve.Add(
                            new CurvePoint(
                                    x:Convert.ToSingle(point[0]),
                                    y:Convert.ToSingle(point[1])
                                )
                            );
                        if (rd.EndOfStream)
                            break;
                    }
                    btnShowCurve_Click(sender, e);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message);
                }
                finally
                {
                    rd.Close();
                    rd.Dispose();
                    RefreshDataViewer();
                }
            };

            saveCurveDialog.InitialDirectory = Application.StartupPath;
            saveCurveDialog.Filter = importDialog.Filter;
            saveCurveDialog.DefaultExt = ".txt";

            saveCurveDialog.FileOk += (send, ev) => {
                var wr = new StreamWriter(saveCurveDialog.FileName);
                try
                {
                    for(int i=0;i<torque_iq_curve.Count;i++)
                    {
                        wr.WriteLine($"{torque_iq_curve[i].x},{torque_iq_curve[i].y}");
                    }
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message);
                }
                finally
                {
                    wr.Close();
                    wr.Dispose();
                }
            };
        }

        public static double[][] ToPoints(ObservableCollection<CurvePoint> curve)
        {
            var x = new List<double>();
            var y = new List<double>();
            for (int i = 0; i < curve.Count; i++)
            {
                x.Add(curve[i].x);
                y.Add(curve[i].y);
            }
            return new double[][] { x.ToArray(), y.ToArray() };
        }

        private void btnShowCurve_Click(object sender, EventArgs e)
        {
            double[][] points = ToPoints(torque_iq_curve);
            grapher.ShowCurve("torque-iq", points[0], points[1]);
        }

        private void RefreshDataViewer()
        {
            CurveDataViewer.DataSource = null;
            CurveDataViewer.DataSource = torque_iq_curve;
            CurveDataViewer.Refresh();
        }

        private void btnAddPoint_Click(object sender, EventArgs e)
        {
            if(torque_iq_curve.Count == 20)
            {
                MessageBox.Show("At Most 20 Points is Supported.");
                return;
            }
            torque_iq_curve.Add(new CurvePoint());
            RefreshDataViewer();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            var len = torque_iq_curve.Count;
            if (len <= 1) return;
            torque_iq_curve.Remove(torque_iq_curve[len - 1]);
            RefreshDataViewer();
        }

        private void btnDownloadCurve_Click(object sender, EventArgs e)
        {
            FormMain.SerialDriver_.Master.WevPidCurve.point_counts = (byte)torque_iq_curve.Count;
            for (int i = 0; i < torque_iq_curve.Count; i++)
            {
                FormMain.SerialDriver_.Master.WevPidCurve.points[i].x = torque_iq_curve[i].x;
                FormMain.SerialDriver_.Master.WevPidCurve.points[i].y = torque_iq_curve[i].y;
            }
            FormMain.SerialDriver_.DownloadPicCurveAnsyc(); //防止粘包，所以用异步的方式放在一个发送循环里面去处理
            var t = new System.Timers.Timer(200) 
            { 
                Enabled = true,
                AutoReset = false
            };
            t.Elapsed += (send, ev) =>
            {
                if(FormMain.SerialDriver_.DownloadCurveConfirmed && !FormMain.SerialDriver_.DownloadingPidCurve)
                {
                    MessageBox.Show("Downlaod Successfully.");
                }
                else
                {
                    MessageBox.Show("Download Failed!", "WARNING", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            };
        }

        private void FormUserCurves_FormClosing(object sender, FormClosingEventArgs e)
        {
            Hide();
            e.Cancel = true;
        }

        private void importToolStripMenuItem_Click(object sender, EventArgs e)
        {
            importDialog.ShowDialog();
        }

        private void saveCurveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveCurveDialog.ShowDialog();
        }
    }
}
